package com.icxcc.workflow.controller;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("expense")
public class ExpenseController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;
    @Qualifier("processEngine")
    @Autowired
    private ProcessEngine processEngine;

    @PostMapping("add")
    public String addExpense(@RequestParam Map<String, Object> param){
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Expense",param);
        return "提交成功"+processInstance.getId();
    }

    @GetMapping("list")
    public Object list(String userId){
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(userId)
                .orderByTaskCreateTime()
                .desc().list();
        tasks.forEach(task -> System.out.println(tasks.toString()));
        return tasks.toArray().toString();
    }

    @GetMapping("apply/{taskId}")
    public String apply(@PathVariable String taskId){
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task==null){
            throw new RuntimeException("");
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("outcome","通过");
        taskService.claim(taskId,"");
        taskService.complete(taskId, map);
        return "processed ok!";
    }

    @GetMapping("reject/{taskId}")
    public String reject(@PathVariable String taskId){
        Map<String, Object> map = new HashMap<>();
        map.put("outcome","驳回");
        taskService.complete(taskId, map);
        return "reject";
    }

    /**
     * 成流程图
     * @param httpServletResponse
     * @param processId
     * @throws IOException
     */
    @GetMapping("processDiagram")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws IOException {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processId).singleResult();
        if (processInstance==null){
            return;
        }
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstance.getId())
                .singleResult();
        //使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
        String instanceId = task.getProcessInstanceId();
        List<Execution> executions = runtimeService.createExecutionQuery()
                .processInstanceId(instanceId)
                .list();
        List<String> flows = new ArrayList<>();
        //得到正在执行的Activity的Id
        List<String> activityIds = executions.stream().map(Execution::getActivityId).collect(Collectors.toList());
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        ProcessEngineConfiguration engineConfig = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engineConfig.getProcessDiagramGenerator();

        InputStream in = diagramGenerator.generateDiagram(bpmnModel,"png", activityIds, flows,
                engineConfig.getActivityFontName(),
                engineConfig.getLabelFontName(),
                engineConfig.getActivityFontName(), engineConfig.getClassLoader(), 1.0, true);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int length = 0;
        try {
            out = httpServletResponse.getOutputStream();
            while ((length=in.read(buf)) != -1){
                out.write(buf,0, length);
            }
            out.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null){
                in.close();
            }
            if (out != null){
                out.close();
            }
        }

    }

    @GetMapping("history")
    public Object history(){
        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery().finished().list();
        tasks.forEach(t-> System.out.println(t.toString()));
        return tasks;
    }
}
